﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;

public class JoyStickScript : MonoBehaviour {

	// Use this for initialization
	SpriteRenderer circleRenderer;
	SpriteRenderer circleStartRenderer;
	SpriteRenderer circleEndRenderer;

	Vector3 rendInitialMin;
	Vector3 rendInitialMax;
	float initialDistance = 0f;
	TextMesh circleText;
	float lastColorAlpha = 0f;
	float colorAlpha = 0.01f;

	public float XMovement = 0f;
	public float YMovement = 0f;
	public float DistanceMoved = 0f;

	public event System.EventHandler FireButtonPressedEvent;
	bool canShoot = true;
	float shootCoolDown = 0.0f;
	float shootCoolDownStart = 0.3f;

	Dictionary<int, Vector2> fingerStartPositions;
	Dictionary<int, Touch> fingers;

	TextMesh debug1;
	TextMesh debug2;
	TextMesh debug3;
	TextMesh debug4;

	void SetColorAlpha() {
		if (colorAlpha > 0f) {
			colorAlpha -= Time.deltaTime;
		}
		if (lastColorAlpha != colorAlpha) {
			lastColorAlpha = colorAlpha;
			Color col = this.circleStartRenderer.color;
			col.a = colorAlpha * 0.25f;
			this.circleStartRenderer.color = col;
			col.a = colorAlpha;
			this.circleEndRenderer.color = col;
			this.circleRenderer.color = col;
			this.circleText.color = col;
		}
	}

	void Start () {
		//Input.multiTouchEnabled = true;

		this.fingers = new Dictionary<int, Touch>();
		this.fingerStartPositions = new Dictionary<int, Vector2>();

		this.circleRenderer = (SpriteRenderer)GameObject.Find("Circle").GetComponent(typeof(SpriteRenderer));
		this.circleStartRenderer = (SpriteRenderer)GameObject.Find("CircleStart").GetComponent(typeof(SpriteRenderer));
		this.circleEndRenderer = (SpriteRenderer)GameObject.Find("CircleEnd").GetComponent(typeof(SpriteRenderer));

		this.debug1 = (TextMesh)GameObject.Find("DebuggingText1").GetComponent(typeof(TextMesh));
		this.debug2 = (TextMesh)GameObject.Find("DebuggingText2").GetComponent(typeof(TextMesh));
		this.debug3 = (TextMesh)GameObject.Find("DebuggingText3").GetComponent(typeof(TextMesh));
		this.debug4 = (TextMesh)GameObject.Find("DebuggingText4").GetComponent(typeof(TextMesh));

		// Scale at a distance of 2.4 should be 0.25;
		// At 9.6 should be 1.0

		//this.rendInitialMin = Camera.main.ScreenToWorldPoint(this.circleRenderer.bounds.min);
		//this.rendInitialMax = Camera.main.ScreenToWorldPoint(this.circleRenderer.bounds.max);
		//float xDistance = Mathf.Abs(this.rendInitialMax.x - this.rendInitialMin.x);
		//float yDistance = Mathf.Abs(this.rendInitialMax.y - this.rendInitialMin.y);
		//this.initialDistance = Mathf.Sqrt(xDistance * xDistance + yDistance * yDistance);

		this.circleText = (TextMesh)GameObject.Find("CircleText").GetComponent(typeof(TextMesh));
		this.circleText.text = this.initialDistance.ToString();

		this.SetColorAlpha();
	}

	void UpdateJoystickGraphics(int fingerId) {
		this.colorAlpha = 1f;
		
		Vector2 currentPos = Camera.main.ScreenToWorldPoint(this.fingers[fingerId].position);
		Vector2 startPos = Camera.main.ScreenToWorldPoint(this.fingerStartPositions[fingerId]);
		
		float xDistance = currentPos.x - startPos.x;
		float yDistance = currentPos.y - startPos.y;
		float distance = Mathf.Sqrt(xDistance * xDistance + yDistance * yDistance);

		float scaleFactor = Mathf.Lerp(0f,1f,distance / 9.6f);
		
		Vector3 topLeftPos = new Vector3(startPos.x - distance, startPos.y - distance, 0f);
		Vector3 botRightPos = new Vector3(startPos.x + distance, startPos.y + distance, 0f);
		this.circleRenderer.transform.position = startPos;
		this.circleRenderer.transform.localScale = new Vector3(scaleFactor,scaleFactor,1f);
		
		this.circleStartRenderer.transform.position = startPos;
		this.circleEndRenderer.transform.position = currentPos;
		this.circleText.text = System.String.Format("{0:F2} ({1:F2},{2:F2})",distance,xDistance,yDistance);
		
		this.DistanceMoved = distance;
		this.XMovement = xDistance;
		this.YMovement = yDistance;
	}

	void UpdateJoystickGraphics(Vector2 sPos, Vector2 pos) {
		this.colorAlpha = 1f;
		
		Vector2 currentPos = Camera.main.ScreenToWorldPoint(pos);
		Vector2 startPos = Camera.main.ScreenToWorldPoint(sPos);
		
		float xDistance = currentPos.x - startPos.x;
		float yDistance = currentPos.y - startPos.y;
		float distance = Mathf.Sqrt(xDistance * xDistance + yDistance * yDistance);
		
		float scaleFactor = Mathf.Lerp(0f,1f,distance / 9.6f);
		
		Vector3 topLeftPos = new Vector3(startPos.x - distance, startPos.y - distance, 0f);
		Vector3 botRightPos = new Vector3(startPos.x + distance, startPos.y + distance, 0f);
		this.circleRenderer.transform.position = startPos;
		this.circleRenderer.transform.localScale = new Vector3(scaleFactor,scaleFactor,1f);
		
		this.circleStartRenderer.transform.position = startPos;
		this.circleEndRenderer.transform.position = currentPos;
		this.circleText.text = System.String.Format("{0:F2} ({1:F2},{2:F2})",distance,xDistance,yDistance);
		
		this.DistanceMoved = distance;
		this.XMovement = xDistance;
		this.YMovement = yDistance;
	}

	/*
	void UpdateJoystickGraphics() {

		if (GameMaintainerSingleton.Instance.CurrentFingerId != GameMaintainerSingleton.Instance.StartFingerId && Input.touchCount == 1) {
			this.DistanceMoved = 0f;
			this.XMovement = 0f;
			this.YMovement = 0f;
			return;
		}

		this.colorAlpha = 1f;
		
		Vector2 currentPos = Camera.main.ScreenToWorldPoint(GameMaintainerSingleton.Instance.Pos);
		Vector2 startPos = Camera.main.ScreenToWorldPoint(GameMaintainerSingleton.Instance.ClickDownPos);
		
		float xDistance = currentPos.x - startPos.x;
		float yDistance = currentPos.y - startPos.y;
		float distance = Mathf.Sqrt(xDistance * xDistance + yDistance * yDistance);
		
		float scaleFactor = Mathf.Lerp(0f,1f,distance / 9.6f);
		
		Vector3 topLeftPos = new Vector3(startPos.x - distance, startPos.y - distance, 0f);
		Vector3 botRightPos = new Vector3(startPos.x + distance, startPos.y + distance, 0f);
		this.circleRenderer.transform.position = startPos;
		this.circleRenderer.transform.localScale = new Vector3(scaleFactor,scaleFactor,1f);
		
		this.circleStartRenderer.transform.position = startPos;
		this.circleEndRenderer.transform.position = currentPos;
		this.circleText.text = System.String.Format("{0:F2} ({1:F2},{2:F2})",distance,xDistance,yDistance);
		
		this.DistanceMoved = distance;
		this.XMovement = xDistance;
		this.YMovement = yDistance;

		if (Input.touchCount > 1) {
			for(int z=1;z<Input.touchCount;z++) {
				Touch letouch = Input.GetTouch(z);
				if (letouch.position.x >= (float)(Screen.width / 2)) {
					if (this.FireButtonPressedEvent != null) {
						if (shootCoolDown <= 0f) {
							this.FireButtonPressedEvent(this, new System.EventArgs());
							//canShoot = false;
							shootCoolDown = shootCoolDownStart;
						}
					}
					if (shootCoolDown > 0.0f) {
						shootCoolDown -= Time.deltaTime;
					}
				}

			}
		}
	}
	*/

	// Update is called once per frame
	void Update () {
		bool wasMouseUpdated = false;
		if (Input.touchCount > 0) {
			this.debug3.text = Input.touchCount.ToString();
			StringBuilder sb = new StringBuilder();
			for (int z=0;z<Input.touchCount;z++) {
				Touch ltouch = Input.GetTouch(z);
				if (ltouch.phase == TouchPhase.Ended) {
					int id = ltouch.fingerId;
					if (this.fingers.ContainsKey(id)) {
						this.fingers.Remove(id);
					}
					if (this.fingerStartPositions.ContainsKey(id)) {
						this.fingerStartPositions.Remove(id);
					}
				}
				else if (this.fingers.ContainsKey(ltouch.fingerId)) {
					this.fingers[ltouch.fingerId] = ltouch;
				}
				else {
					if (ltouch.phase == TouchPhase.Began) {
						this.fingers.Add(ltouch.fingerId, ltouch);
						this.fingerStartPositions.Add(ltouch.fingerId, ltouch.position);
					}
				}

				sb.Append(string.Format("({0},({1})), ",ltouch.fingerId,ltouch.position.ToString()));
			}
			this.debug4.text = sb.ToString();
		}
		else if (GameMaintainerSingleton.Instance.CheckInTouchInteractionState()) {
			wasMouseUpdated = true;
			this.UpdateJoystickGraphics(GameMaintainerSingleton.Instance.ClickDownPos, GameMaintainerSingleton.Instance.Pos);
		}
		else {
			this.fingers = new Dictionary<int, Touch>();
			this.fingerStartPositions = new Dictionary<int, Vector2>();
			this.DistanceMoved = 0f;
			this.XMovement = 0f;
			this.YMovement = 0f;
			this.shootCoolDown = 0f;

			this.debug3.text = "0";
			this.debug4.text = "0";
		}

		
		float halfScreen = (float)(Screen.width / 2);
		bool anyKeysOnLeft = false;
		foreach(KeyValuePair<int,Vector2> kvp in this.fingerStartPositions) {
			Touch currentFinger = this.fingers[kvp.Key];
			// If we've tapped on the right side of the screen we'll fire
			if (kvp.Value.x >= halfScreen && currentFinger.position.x >= halfScreen) {
				if (currentFinger.phase == TouchPhase.Began) {
					shootCoolDown = 0f;
				}
				if (this.FireButtonPressedEvent != null) {
					if (shootCoolDown <= 0f) {
						this.FireButtonPressedEvent(this, new System.EventArgs());
						//canShoot = false;
						shootCoolDown = shootCoolDownStart;
					}
				}
				if (shootCoolDown > 0.0f) {
					shootCoolDown -= Time.deltaTime;
				}

			}
			// If we're on the left side of the screen we use the joystick
			if (kvp.Value.x < halfScreen) {
				this.UpdateJoystickGraphics(kvp.Key);
				anyKeysOnLeft = true;
			}
		}
		if (!anyKeysOnLeft && !wasMouseUpdated) {
			this.DistanceMoved = 0f;
			this.XMovement = 0f;
			this.YMovement = 0f;
		}

		if (Input.GetKeyDown(KeyCode.Space)) {
			if (this.FireButtonPressedEvent != null) {
				this.FireButtonPressedEvent(this, new System.EventArgs());
			}
		}
		if (Application.isEditor) {
			//Debug.Log("EDITOR");
		}
		
		/*
		if (GameMaintainerSingleton.Instance.CheckInTouchInteractionState()) {

			this.debug1.text = "In interaction state";

			if (GameMaintainerSingleton.Instance.ClickDownPos.x < (float)(Screen.width / 2)) {
				this.debug2.text = "In left half";
				UpdateJoystickGraphics();
			}
			else {
				this.debug2.text = "In right half";
				// Fire Button
				if (this.FireButtonPressedEvent != null) {
					if (shootCoolDown <= 0f) {
						this.FireButtonPressedEvent(this, new System.EventArgs());
						//canShoot = false;
						shootCoolDown = shootCoolDownStart;
					}
				}
				if (shootCoolDown > 0.0f) {
					shootCoolDown -= Time.deltaTime;
				}
			}
		}
		else {
			this.debug1.text = "not in interaction";

			if (shootCoolDown > 0.0f) {
				shootCoolDown -= Time.deltaTime;
			}
			this.DistanceMoved = 0f;
			this.XMovement = 0f;
			this.YMovement = 0f;
		}
		*/
		this.SetColorAlpha();
	}
}
